package com.mornd.gulimall.order.receiver;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.mornd.gulimall.order.config.pay.AliPayAsyncVo;
import com.mornd.gulimall.order.config.pay.AlipayProperties;
import com.mornd.gulimall.order.service.IOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author: mornd
 * @dateTime: 2023/8/28 - 12:04
 * 支付宝支付成功，接收支付宝的异步通知
 */

@Slf4j
@RestController
public class OrderPayedReceiver {
    @Resource
    private IOrderService orderService;
    @Resource
    private AlipayProperties alipayProperties;

    // application/x-www-form-urlencoded;charset=utf-8 不需要添加RequestBody
    @RequestMapping(value = "/payed/order/notify", method = RequestMethod.POST)
    public String handle(AliPayAsyncVo vo, HttpServletRequest request) throws AlipayApiException {
        log.debug("接收到alipay支付成功异步回调请求");
        Map<String, String[]> requestParameterMap = request.getParameterMap();

        // map转换
        Map<String, String> params = new HashMap<>();
        for (Iterator<String> iter = requestParameterMap.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParameterMap.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        // 签名校验
        boolean signValid = AlipaySignature.rsaCheckV1(params,
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getCharset(),
                alipayProperties.getSignType());

        if (signValid) {
            try {
                orderService.handlePayedResult(vo);
                // 必须指定返回success，否则会继续发送通知
                return "success";
            } catch (Exception e) {
                log.error(e.getMessage());
                return "error";
            }
        } else {
            return "invalid sign";
        }
    }
}
